package com.dwxt.parabolic.service;

import com.dwxt.common.base.BaseResult;
import com.dwxt.common.base.Page;
import com.dwxt.common.base.StatusCode;
import com.dwxt.common.base.YesOrNo;
import com.dwxt.common.util.IDUtils;
import com.dwxt.common.util.JsonUtils;
import com.dwxt.common.util.MD5Utils;
import com.dwxt.parabolic.base.QuantityType;
import com.dwxt.parabolic.base.RoleType;
import com.dwxt.parabolic.dao.UserMapper;
import com.dwxt.parabolic.dao.UserRoleMapper;
import com.dwxt.parabolic.entity.*;
import com.dwxt.parabolic.utils.RedisUtil;
import com.dwxt.parabolic.utils.RequestUtil;
import com.dwxt.parabolic.utils.TokenUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.bouncycastle.jcajce.provider.digest.MD2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CompanyService companyService;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private InstallCompanyService installCompanyService;


    @Transactional
    public BaseResult addCompanyUser(User user) {
        User selectByPhone = selectByPhone(user.getPhoneNumber());
        if (selectByPhone != null) {
            return BaseResult.build(StatusCode.PHONE_EXIST);
        }

        //插入管理用户信息
        user.setId(IDUtils.genItemId());
        user.setIsManager(YesOrNo.NO);
        user.setPassword(MD5Utils.MD5Encode(user.getPassword() == null ? "123456" : user.getPassword()));
        //user.setRoleId("3");
        userMapper.insertSelective(user);

        //更改公司人员数量,数量+1
        if (RoleType.COMPANY.getType().equalsIgnoreCase(user.getRoleId())) {
            companyService.addByQuantityType(user.getCompanyId(), QuantityType.user, 1);
        } else if (RoleType.INSTALL_COMPANY.getType().equalsIgnoreCase(user.getRoleId())) {
            installCompanyService.addByQuantityType(user.getCompanyId(), QuantityType.user, 1);
        }
        return BaseResult.ok();

    }

    public BaseResult getUserList(User user, Page page) {
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        UserExample example = new UserExample();
        example.setOrderByClause("is_manager desc,create_time desc");
        UserExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(user.getCompanyId())) {
            criteria.andCompanyIdEqualTo(user.getCompanyId());
        } else {
            criteria.andRoleIdEqualTo("2").andIsManagerEqualTo(YesOrNo.YES);
        }
        if (StringUtils.isNotBlank(user.getPhoneNumber())) {
            criteria.andPhoneNumberEqualTo(user.getPhoneNumber());
        }
        if (StringUtils.isNotBlank(user.getUserName())) {
            criteria.andUserNameLike("%" + user.getUserName() + "%");
        }
        if (Optional.of(user).map(User::getStatus).isPresent()) {
            criteria.andStatusEqualTo(user.getStatus());
        }
        List<User> users = userMapper.selectByExample(example);

        PageInfo pageInfo = new PageInfo(users);
        return BaseResult.ok(pageInfo);
    }

    public BaseResult update(User user) {
        if (Optional.ofNullable(user).map(User::getPassword).isPresent()) {
            user.setPassword(MD5Utils.MD5Encode(user.getPassword()));
        }
        userMapper.updateByPrimaryKeySelective(user);
        return BaseResult.ok();
    }

    @Transactional
    public BaseResult add(User user) {
        user.setId(IDUtils.genItemId());
        userMapper.insertSelective(user);
        //增加角色记录
        UserRole userRole = UserRole.builder().roleId(user.getRoleId()).userId(user.getId()).build();
        userRoleMapper.insertSelective(userRole);
        return BaseResult.ok();
    }

    public BaseResult login(String phoneNumber, String password) {
        User user = selectByPhone(phoneNumber);
        if (!Optional.ofNullable(user)
                .filter(u -> MD5Utils.MD5Encode(password).equalsIgnoreCase(u.getPassword()) && u.getStatus() == YesOrNo.YES).isPresent()) {
            return BaseResult.build(StatusCode.USERNAME_PASSWORD_WRONG);
        }
        String token = TokenUtil.makeToken();
        RedisUtil.set(token, user.getCompanyId() + "," + user.getId() + "," + user.getRoleId(), (long) 7 * 24 * 60 * 60);
        Map map = new HashMap();
        map.put("user", user);
        map.put("token", token);
        return BaseResult.ok(map);
    }

    public User selectByPhone(String phoneNumber) {
        UserExample example = new UserExample();
        example.createCriteria().andPhoneNumberEqualTo(phoneNumber);
        List<User> users = userMapper.selectByExample(example);
        return users.size() > 0 ? users.get(0) : null;
    }

    /**
     * 是否有已经绑定过的用户
     * @param openId
     * @return
     */
    public boolean selectByOpenId(String openId) {
        UserExample example = new UserExample();
        example.createCriteria().andOpenIdEqualTo(openId).andIsBindEqualTo(1);
        List<User> users = userMapper.selectByExample(example);
        return users.size() > 0 ? false : true;
    }

    public BaseResult getCurrentUserList() {
        List<User> userList = selectByCompanyId(RequestUtil.getCurrentCompanyId());
        return BaseResult.ok(userList);
    }

    public List<User> selectByCompanyId(String companyId) {
        UserExample example = new UserExample();
        example.setOrderByClause("is_manager desc,create_time");
        example.createCriteria().andCompanyIdEqualTo(companyId);
        return userMapper.selectByExample(example);
    }

    public BaseResult selectCurrentLoginUser() {
        //User user = ;
        return BaseResult.ok(userMapper.selectByPrimaryKey(RequestUtil.getCurrentUserId()));
    }

    public void insertSelective(User user) {
        userMapper.insertSelective(user);
    }

    public BaseResult delete(String id) {
        User user = userMapper.selectByPrimaryKey(id);
        userMapper.deleteByPrimaryKey(id);
        if (user.getRoleId().equals(RoleType.INSTALL_COMPANY.getType())) {
            //InstallCompany installCompany = installCompanyService.selectByPrimaryKey(user.getCompanyId());
            installCompanyService.addByQuantityType(user.getCompanyId(), QuantityType.user, -1);
        } else if (user.getRoleId().equals(RoleType.COMPANY.getType())) {
            companyService.addByQuantityType(user.getCompanyId(), QuantityType.user, -1);
        }
        return BaseResult.ok();
    }

    public User selectByPrimaryKey(String userId) {
        return userMapper.selectByPrimaryKey(userId);
    }

    public void deleteByCompanyId(String companyId) {
        UserExample example = new UserExample();
        example.createCriteria().andCompanyIdEqualTo(companyId);
        userMapper.deleteByExample(example);
    }

    public void endByInstallCompanyId(String id) {
        List<String> companyIdList = companyService.selectByInstallCompanyId(id).stream().map(Company::getId).collect(Collectors.toList());
        companyIdList.add(id);
        UserExample example = new UserExample();
        example.createCriteria().andCompanyIdIn(companyIdList);
        User user = User.builder().status(YesOrNo.NO).build();
        userMapper.updateByExampleSelective(user, example);
    }

    public void startByInstallCompanyId(String id) {
        UserExample example = new UserExample();
        example.createCriteria().andCompanyIdEqualTo(id);
        User user = User.builder().status(YesOrNo.YES).build();
        userMapper.updateByExampleSelective(user, example);
    }

    public void updateByCompanyId(String id, int status) {
        UserExample example = new UserExample();
        example.createCriteria().andCompanyIdEqualTo(id);
        User user = User.builder().status(status).build();
        userMapper.updateByExampleSelective(user, example);
    }
}
